From 4384b3fc7028be8e027d984e4f7e38a0d488211d Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sun, 23 Oct 2005 22:34:13 +0100 Subject: [PATCH] Instead of writing errors to /local/domain/0/backend////error, write them instead to /local/domain/0/error/backend/. This is not the best place for them perhaps, but it moves them out of the backend directory, on which the drivers have a watch. This fixes the problem whereby writing an error will trigger a watch, causing the error message to be written again, and repeat. Fixes bug #286. Signed-off-by: Ewan Mellor --- .../drivers/xen/xenbus/xenbus_xs.c | 60 ++++++++++++++++--- tools/examples/xen-backend.agent | 4 ++ tools/python/xen/util/diagnose.py | 4 +- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index efaffe2393..c8d1204fc2 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -516,17 +516,38 @@ int xenbus_printf(struct xenbus_transaction *t, } EXPORT_SYMBOL(xenbus_printf); +/** + * Return the path to the error node for the given device, or NULL on failure. + * If the value returned is non-NULL, then it is the caller's to kfree. + */ +static char *error_path(struct xenbus_device *dev) +{ + char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) + + 1, GFP_KERNEL); + if (path_buffer == NULL) { + return NULL; + } + + strcpy(path_buffer, "error/"); + strcpy(path_buffer + strlen("error/"), dev->nodename); + + return path_buffer; +} + /* Report a (negative) errno into the store, with explanation. */ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) { va_list ap; int ret; unsigned int len; - char *printf_buffer; + char *printf_buffer = NULL, *path_buffer = NULL; printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); - if (printf_buffer == NULL) + if (printf_buffer == NULL) { + printk("xenbus: failed to write error node for %s (%d): %d\n", + dev->nodename, err, errno); goto fail; + } len = sprintf(printf_buffer, "%i ", -err); va_start(ap, fmt); @@ -535,15 +556,26 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1); dev->has_error = 1; - if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0) + + path_buffer = error_path(dev); + + if (path_buffer == NULL) { + printk("xenbus: failed to write error node for %s (%s): %d\n", + dev->nodename, printf_buffer, errno); goto fail; + } - kfree(printf_buffer); - return; + if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) { + printk("xenbus: failed to write error node for %s (%s)\n", + dev->nodename, printf_buffer); + goto fail; + } - fail: - printk("xenbus: failed to write error node for %s (%s)\n", - dev->nodename, printf_buffer); +fail: + if (printf_buffer) + kfree(printf_buffer); + if (path_buffer) + kfree(path_buffer); } EXPORT_SYMBOL(xenbus_dev_error); @@ -551,11 +583,21 @@ EXPORT_SYMBOL(xenbus_dev_error); void xenbus_dev_ok(struct xenbus_device *dev) { if (dev->has_error) { - if (xenbus_rm(NULL, dev->nodename, "error") != 0) + char *path_buffer = error_path(dev); + + if (path_buffer == NULL) { + printk("xenbus: failed to clear error node for %s: " + "%d\n", dev->nodename, errno); + return; + } + + if (xenbus_rm(NULL, path_buffer, "error") != 0) printk("xenbus: failed to clear error node for %s\n", dev->nodename); else dev->has_error = 0; + + kfree(path_buffer); } } EXPORT_SYMBOL(xenbus_dev_ok); diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 105572102b..35eb79601a 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -15,9 +15,13 @@ case "$ACTION" in vbd) /etc/xen/scripts/block unbind ;; + vif) + [ -n "$script" ] && $script down + ;; esac # remove device backend store entries xenstore-rm -t "$XENBUS_PATH" + xenstore-rm -t "error/$XENBUS_PATH" ;; online) case "$XENBUS_TYPE" in diff --git a/tools/python/xen/util/diagnose.py b/tools/python/xen/util/diagnose.py index d8b765e5c7..201c88120c 100644 --- a/tools/python/xen/util/diagnose.py +++ b/tools/python/xen/util/diagnose.py @@ -107,7 +107,9 @@ def diagnose_devices(): print ("Cannot find backend path for device %s, %s." % (deviceClass, device)) else: - backend_error = xstransact.Read(backendPath, 'error') + backend_error = xstransact.Read( + backendPath.replace('backend/', 'error/backend/'), + 'error') if backend_error: diagnose_device_error(backend_error) -- 2.30.2